package com.fuyun.microservice.connect;

import com.google.common.util.concurrent.ListeningScheduledExecutorService;
import com.google.common.util.concurrent.MoreExecutors;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicInteger;

@Slf4j
public class EventLoopGroupFactory {

    private final static RejectedExecutionHandler rejected = new RejectedExecutionHandler(){
        @Override
        public void rejectedExecution(Runnable r, ThreadPoolExecutor executor){
            log.debug("task ignored");
        }
    };

    private final static int DEFAULT_THREAD_NUM =  Runtime.getRuntime().availableProcessors()*2;
    private  final static EventLoopGroup bossGroup = new NioEventLoopGroup(1, newThreadFactory("bossGroup"));
    private  final static EventLoopGroup workgroup = new NioEventLoopGroup(DEFAULT_THREAD_NUM, newThreadFactory("workGroup"));
    public   final static EventLoopGroup proxyGroup = new NioEventLoopGroup(64, newThreadFactory("proxyGroup"));

    private final static ListeningScheduledExecutorService busiWork = MoreExecutors.listeningDecorator(new ScheduledThreadPoolExecutor(4,newThreadFactory("busiWork-"),rejected));

    public static EventLoopGroup getBoss(){return bossGroup;}

    public static EventLoopGroup getWorker(){
        return workgroup;
    }

    public static ListeningScheduledExecutorService getBusiWork(){return busiWork;}

    private static ThreadFactory newThreadFactory(final String name){

        return new ThreadFactory() {

            private final AtomicInteger threadNumber = new AtomicInteger(1);

            @Override
            public Thread newThread(Runnable r) {
                Thread t = new Thread( r,name + threadNumber.getAndIncrement());

                t.setDaemon(true);
                if (t.getPriority() != Thread.NORM_PRIORITY) {
                    t.setPriority(Thread.NORM_PRIORITY);
                }
                return t;
            }
        };
    }
}
